package com.mvvmhabit.org.base

import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.PopupWindow
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModelProvider
import com.mvvmhabit.org.R
import com.mvvmhabit.org.bus.Messenger
import com.mvvmhabit.org.utils.ScreenUtil

abstract class BasePopupWindow<V : ViewDataBinding, VM : BaseViewModel>(val context: FragmentActivity) :
    PopupWindow(context) {

    lateinit var mBinding: V

    var mViewModel: VM? = null

    private var viewModelId: Int = 0

    abstract fun layoutId(): Int

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    abstract fun initVariableId(): Int

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    abstract fun initViewModel(): Class<VM>


    init {
        initView()
    }

    private fun initView() {
        mBinding = DataBindingUtil.inflate(
            LayoutInflater.from(context),
            layoutId(),
            null,
            false
        )
        contentView = mBinding.root
        if (mViewModel == null) {
            mViewModel = ViewModelProvider(context).get(initViewModel())
            viewModelId = initVariableId()
            mBinding.setVariable(viewModelId, mViewModel)
            context.lifecycle.addObserver(mViewModel!!)
            mViewModel?.injectLifecycleProvider(context)
            registerUIChangeLiveEventCallBack()
            width = ViewGroup.MarginLayoutParams.MATCH_PARENT
            height = initHeight()
            setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            // 是否响应外部点击事件
            isOutsideTouchable = false
            isFocusable = true
            // 设置popupWindow动画
            animationStyle = R.style.anim_popup_gradient
            initData()
            initViewObservable()
            backgroundAlpha(setBackgroundAlpha())
        }
        mViewModel?.registerBus()
    }

    override fun dismiss() {
        super.dismiss()
        backgroundAlpha(1F)
    }

    /**
     * 设置添加屏幕的背景透明度
     *
     * @param bgAlpha
     */
    private fun backgroundAlpha(bgAlpha: Float) {
        val lp: WindowManager.LayoutParams = context.window.attributes
        lp.alpha = bgAlpha //0.0-1.0
        context.window.attributes = lp
        context.window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
    }

    open fun setBackgroundAlpha(): Float {
        return 1F
    }

    private fun registerUIChangeLiveEventCallBack() {
        // 页面跳转
        mViewModel?.getUI()?.getStartActivityEvent()?.observeForever {
            val clz: Class<*> = it[CLASS] as Class<*>
            val bundle: Any? = it[BUNDLE]
            startActivity(clz, bundle)
        }
        // 跳转到容器页面
        mViewModel?.getUI()?.getStartContainerActivityEvent()?.observeForever {
            val canonicalName = it[CANONICAL_NAME] as String
            val bundle = it[BUNDLE]
            startContainerActivity(canonicalName, bundle)
        }
        // 关闭界面
        mViewModel?.getUI()?.getFinishEvent()?.observeForever {
            context.finish()
        }

        mViewModel?.getUI()?.getStartIntentEvent()?.observeForever {
            context.startActivity(it)
        }
    }

    protected fun startActivity(clz: Class<*>, bundle: Any?) {
        val intent = Intent(context, clz)
        if (bundle != null) {
            intent.putExtras(bundle as Bundle)
        }
        context.startActivity(intent)
    }

    protected fun startContainerActivity(canonicalName: String?, bundle: Any?) {
        val intent = Intent(context, ContainerActivity::class.java)
        intent.putExtra(FRAGMENT, canonicalName)
        if (bundle != null) {
            intent.putExtra(FRAGMENT_BUNDLE, bundle as Bundle)
        }
        context.startActivity(intent)
    }

    open fun initData() {

    }

    open fun initViewObservable() {

    }

    open fun initHeight(): Int {
        return ScreenUtil.dp2px(context, 200f)
    }

    open fun onDestroy() {
        Messenger.getDefault().unregister(mViewModel)
        if (mViewModel != null) {
            mViewModel?.removeBus()
        }
        mBinding.unbind()
    }
}